#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/wait.h>

// void sig_usr(int signal)
// {
//     printf("have received SIGUSR signal!\n");
// }

void sig_usr(int signal){
    int status;
    switch (signal)
    {
    case SIGUSR1:
        printf("SIGUSR1 received!, process id is %d\n", getpid());
        break;

    case SIGCHLD:
        printf("SIGCHLD received!, process id is %d\n",getpid());
        // 新函数 waitpid,也有用wait函数的, 建议使用 waitpid函数就可以了
        // waitpid声明在 <sys/wait.h>, 使用#include预处理命令包含
        pid_t pid = waitpid(-1, &status, WNOHANG);
        // 1参数,"-1" 表示等待任何子进程
        // 2参数, 保存子进程的状态信息,
        // 3参数, 额外选项,WNOHANG表示不要阻塞,让waitpid()立即返回

        // 这里子进程还没有结束, 会立即返回该数字
        // 但是这里应该不是该数字, 这里的情况是子进程结束才触发父进程的该信号
        if (pid == 0)
        {
            return;
        }

        // 表示这个waitpid调用有错误. 但是这里管不了这么多了,(摆烂)
        if (pid == -1)
        {
            return;
        }
        return;
        break;
    }
}


int main(int argc, char const *argv[])
{
    pid_t pid;
    printf("Process starting......\n");

    // 将sig_usr函数绑定在SIGUSR1信号上
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
    {
        printf("CANNOT capture SIGUSR signal\n");
        exit(-1);
    }

    // 将sig_usr函数绑定在SIGCHLD信号上
    if (signal(SIGCHLD, sig_usr) == SIG_ERR)
    {
        printf("CANNOT capture SIGCHLD signal\n");
        exit(-1);
    }

    // 创建一个子进程
    pid = fork();

    if (pid < 0)
    {
        printf("child process creating FAILED!!\n");
        exit(-1);
    }

    // fork时候子进程和父进程同时开始执行了
    while (true)
    {
        sleep(1);
        printf("sleep for 1sec, processid is %d!\n", getpid());
    }

    printf("bye!\n");

    return 0;
}
